"""
日志系统模块

提供结构化日志、日志轮转、多级别日志输出等功能。
基于 loguru 实现，支持灵活的日志配置。
"""

import sys
import os
from pathlib import Path
from typing import Optional, Dict, Any, Union
from loguru import logger
from ..config.settings import get_settings


class LoggerManager:
    """日志管理器"""
    
    def __init__(self):
        self._initialized = False
        self._logger_id = None
    
    def setup_logger(self, config: Optional[Dict[str, Any]] = None) -> None:
        """设置日志系统
        
        Args:
            config: 日志配置，如果为None则使用全局配置
        """
        if self._initialized:
            return
        
        # 获取配置
        if config is None:
            settings = get_settings()
            config = settings.config.logging.dict()
        
        # 移除默认处理器
        logger.remove()
        
        # 添加控制台处理器
        self._add_console_handler(config)
        
        # 添加文件处理器
        if config.get('file'):
            self._add_file_handler(config)
        
        # 添加审计日志处理器
        settings = get_settings()
        if settings.config.security.audit_log:
            self._add_audit_handler(config)
        
        self._initialized = True
    
    def _add_console_handler(self, config: Dict[str, Any]) -> None:
        """添加控制台日志处理器"""
        level = config.get('level', 'INFO')
        
        # 控制台格式：简洁明了
        console_format = (
            "<green>{time:YYYY-MM-DD HH:mm:ss}</green> | "
            "<level>{level: <8}</level> | "
            "<cyan>{name}</cyan>:<cyan>{function}</cyan>:<cyan>{line}</cyan> | "
            "<level>{message}</level>"
        )
        
        logger.add(
            sys.stderr,
            format=console_format,
            level=level,
            colorize=True,
            backtrace=True,
            diagnose=True
        )
    
    def _add_file_handler(self, config: Dict[str, Any]) -> None:
        """添加文件日志处理器"""
        log_file = config.get('file', 'es-archive.log')
        level = config.get('level', 'INFO')
        max_size = config.get('max_size', '10MB')
        backup_count = config.get('backup_count', 5)
        
        # 确保日志目录存在
        log_path = Path(log_file)
        log_path.parent.mkdir(parents=True, exist_ok=True)
        
        # 文件格式：详细信息
        file_format = (
            "{time:YYYY-MM-DD HH:mm:ss.SSS} | "
            "{level: <8} | "
            "{process.id} | "
            "{thread.id} | "
            "{name}:{function}:{line} | "
            "{message}"
        )
        
        # 添加时区信息
        if config.get('include_timezone', True):
            if config.get('time_format') == 'ISO8601':
                file_format = file_format.replace(
                    "{time:YYYY-MM-DD HH:mm:ss.SSS}",
                    "{time:YYYY-MM-DD HH:mm:ss.SSSZ}"
                )
        
        logger.add(
            log_file,
            format=file_format,
            level=level,
            rotation=max_size,
            retention=backup_count,
            compression="gz",
            encoding="utf-8",
            backtrace=True,
            diagnose=True
        )
    
    def _add_audit_handler(self, config: Dict[str, Any]) -> None:
        """添加审计日志处理器"""
        audit_file = "es-archive-audit.log"
        
        # 确保审计日志目录存在
        audit_path = Path(audit_file)
        audit_path.parent.mkdir(parents=True, exist_ok=True)
        
        # 审计日志格式：结构化JSON
        audit_format = (
            "{{\"timestamp\": \"{time:YYYY-MM-DD HH:mm:ss.SSSZ}\", "
            "\"level\": \"{level}\", "
            "\"process_id\": {process.id}, "
            "\"thread_id\": {thread.id}, "
            "\"module\": \"{name}\", "
            "\"function\": \"{function}\", "
            "\"line\": {line}, "
            "\"message\": \"{message}\", "
            "\"extra\": {extra}}}"
        )
        
        logger.add(
            audit_file,
            format=audit_format,
            level="INFO",
            rotation="1 day",
            retention="30 days",
            compression="gz",
            encoding="utf-8",
            filter=lambda record: record["extra"].get("audit", False)
        )
    
    def get_logger(self, name: str) -> "LoggerAdapter":
        """获取指定名称的日志器
        
        Args:
            name: 日志器名称
            
        Returns:
            日志器适配器
        """
        if not self._initialized:
            self.setup_logger()
        
        return LoggerAdapter(logger.bind(name=name), name)


class LoggerAdapter:
    """日志器适配器
    
    提供更友好的日志接口和额外功能。
    """
    
    def __init__(self, logger_instance, name: str):
        self._logger = logger_instance
        self._name = name
    
    def debug(self, message: str, **kwargs) -> None:
        """调试日志"""
        self._logger.debug(message, **kwargs)
    
    def info(self, message: str, **kwargs) -> None:
        """信息日志"""
        self._logger.info(message, **kwargs)
    
    def warning(self, message: str, **kwargs) -> None:
        """警告日志"""
        self._logger.warning(message, **kwargs)
    
    def error(self, message: str, **kwargs) -> None:
        """错误日志"""
        self._logger.error(message, **kwargs)
    
    def critical(self, message: str, **kwargs) -> None:
        """严重错误日志"""
        self._logger.critical(message, **kwargs)
    
    def exception(self, message: str, **kwargs) -> None:
        """异常日志（包含堆栈跟踪）"""
        self._logger.exception(message, **kwargs)
    
    def audit(self, message: str, **kwargs) -> None:
        """审计日志"""
        kwargs['audit'] = True
        self._logger.info(message, **kwargs)
    
    def performance(self, operation: str, duration: float, **kwargs) -> None:
        """性能日志"""
        kwargs.update({
            'operation': operation,
            'duration_ms': round(duration * 1000, 2),
            'performance': True
        })
        self._logger.info(f"Performance: {operation} took {duration:.3f}s", **kwargs)
    
    def progress(self, message: str, current: int, total: int, **kwargs) -> None:
        """进度日志"""
        percentage = (current / total * 100) if total > 0 else 0
        kwargs.update({
            'current': current,
            'total': total,
            'percentage': round(percentage, 2),
            'progress': True
        })
        self._logger.info(f"Progress: {message} ({current}/{total}, {percentage:.1f}%)", **kwargs)
    
    def structured(self, message: str, **kwargs) -> None:
        """结构化日志"""
        kwargs['structured'] = True
        self._logger.info(message, **kwargs)
    
    def bind(self, **kwargs) -> "LoggerAdapter":
        """绑定额外的上下文信息"""
        return LoggerAdapter(self._logger.bind(**kwargs), self._name)


# 全局日志管理器实例
_logger_manager = LoggerManager()


def setup_logging(config: Optional[Dict[str, Any]] = None) -> None:
    """设置全局日志系统
    
    Args:
        config: 日志配置
    """
    _logger_manager.setup_logger(config)


def get_logger(name: str = "es_archive") -> LoggerAdapter:
    """获取日志器
    
    Args:
        name: 日志器名称
        
    Returns:
        日志器适配器
    """
    return _logger_manager.get_logger(name)


# 便捷的模块级日志器
def get_module_logger(module_name: str) -> LoggerAdapter:
    """获取模块日志器
    
    Args:
        module_name: 模块名称（通常使用 __name__）
        
    Returns:
        日志器适配器
    """
    # 简化模块名称
    if module_name.startswith('es_archive.'):
        module_name = module_name[11:]  # 移除 'es_archive.' 前缀
    
    return get_logger(module_name)


class LogContext:
    """日志上下文管理器
    
    用于在特定代码块中添加额外的日志上下文信息。
    """
    
    def __init__(self, logger_adapter: LoggerAdapter, **context):
        self._logger = logger_adapter
        self._context = context
        self._bound_logger = None
    
    def __enter__(self) -> LoggerAdapter:
        self._bound_logger = self._logger.bind(**self._context)
        return self._bound_logger
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        pass


# 装饰器：自动记录函数调用
def log_function_call(logger_adapter: Optional[LoggerAdapter] = None):
    """装饰器：自动记录函数调用
    
    Args:
        logger_adapter: 日志器，如果为None则使用默认日志器
    """
    def decorator(func):
        def wrapper(*args, **kwargs):
            nonlocal logger_adapter
            if logger_adapter is None:
                logger_adapter = get_logger(func.__module__)
            
            func_name = f"{func.__module__}.{func.__name__}"
            logger_adapter.debug(f"Calling function: {func_name}")
            
            try:
                result = func(*args, **kwargs)
                logger_adapter.debug(f"Function completed: {func_name}")
                return result
            except Exception as e:
                logger_adapter.error(f"Function failed: {func_name}, error: {e}")
                raise
        
        return wrapper
    return decorator


# 性能监控装饰器
def log_performance(logger_adapter: Optional[LoggerAdapter] = None):
    """装饰器：自动记录函数性能
    
    Args:
        logger_adapter: 日志器，如果为None则使用默认日志器
    """
    import time
    
    def decorator(func):
        def wrapper(*args, **kwargs):
            nonlocal logger_adapter
            if logger_adapter is None:
                logger_adapter = get_logger(func.__module__)
            
            func_name = f"{func.__module__}.{func.__name__}"
            start_time = time.time()
            
            try:
                result = func(*args, **kwargs)
                duration = time.time() - start_time
                logger_adapter.performance(func_name, duration)
                return result
            except Exception as e:
                duration = time.time() - start_time
                logger_adapter.performance(func_name, duration, error=str(e))
                raise
        
        return wrapper
    return decorator
